package com.jpa.web.repository;

import com.jpa.web.model.Employee;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.RepositoryDefinition;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Created by BKWJA on 2018/10/27.
 *  方法名，命名方式，有严格的要求
 *
 *  官方文档：https://docs.spring.io/spring-data/jpa/docs/1.4.3.RELEASE/reference/html/jpa.repositories.html
 *
 *  domainClass = Employee.class ：声明是哪个实体类
 *  idClass = Integer.class ：声明实体类 id 是什么类型
 *
 *  方法一：改接口类，继续 Repository（public interface EmployeeRepository extends Repository<Employee,Integer>）
 *      可以成功调用jpa自带的方法。
 *  方法二：使用注解方式，继承Repository方法 （@RepositoryDefinition(domainClass = Employee.class,idClass = Integer.class)）
 *
 */
@RepositoryDefinition(domainClass = Employee.class,idClass = Integer.class)
public interface EmployeeRepository { // extends Repository<Employee,Integer>


    /**
     * 根据 name ，查询员工信息
     * @param emp_name
     * @return
     */
    public Employee findByEmpname(String emp_name);

    /**
     * 添加
     * saveAndFlush 保存并刷新
     * save 保存
     * @param employee
     */
    public void save(Employee employee);

    /**
     * 查询员工姓名 like name%  并且 年龄 < age (查询name以……开头，并且年龄 < age)
     * @return
     */
    public List<Employee> findByEmpnameStartsWithAndEmpageLessThan(String name,int age);


    /**
     * 查询员工姓名 like %name  并且 年龄 < age  (查询name以……结尾，并且年龄 < age)
     * @return
     */
    public List<Employee> findByEmpnameEndingWithAndEmpageLessThan(String name,int age);

    /**
     * 根据 id ，查询员工信息
     * @param empid
     * @return
     */
    public Employee findByEmpid(Integer empid);

    /**
     *  id in(?,?……) or department = ?
     * @param empids  多个id
     * @param department 一个部门
     * @return
     */
    public List<Employee> findByEmpidInOrDepartment(List<Integer> empids,String department);


    /**
     * 查询所有员工记录 select * from employee
     * @return
     */
    public List<Employee> findAll();

    /**
     * 查询 max（id）的记录
     *  注：@Query from Employee，是类名，不是表名（相当于 HQL）
     * @return
     */
    @Query("select e from Employee e where id=(select max(id) from Employee emp)")
    public Employee getEmployeeByEmpid();

    /**
     * 查询 age = ? and department = ? 之间的员工信息
     * 注： queryParamsl() 这个方法，不是Repository 不是内置函数
     * @param age
     * @param department
     * @return
     */
    @Query("select e from Employee e where e.empage = ?1 and e.department = ?2")
    public List<Employee> queryParamsl(Integer age,String department);


    /**
     * 查询 age = ? and department = ? 之间的员工信息
     * 注： queryParams2() 这个方法，不是Repository 不是内置函数
     * @param age
     * @param department
     * @return
     */
    @Query("select e from Employee e where e.empage = :empage and e.department = :department")
    public List<Employee> queryParams2(@Param("empage") Integer age,@Param("department") String department);


    /**
     * 查询 name like %?%
     * nativeQuery = true :支持原生SQL语句
     * 注： queryParamsLikel() 这个方法，不是Repository 不是内置函数
     * nativeQuery=true :标识为原生的 SQL语句(mysql查询语句)，意思就是 必须是表名，和表字段
     * @param name
     * @return
     */
    @Query(value = "select * from employee where emp_name like %?1%",nativeQuery=true)
    public List<Employee> queryParamsLikel(String name);

    /**
     * 查询 name like %?%
     * nativeQuery = true :支持原生SQL语句
     * 注： queryParamsLike2() 这个方法，不是Repository 不是内置函数
     * nativeQuery=true :标识为原生的 SQL语句(mysql查询语句)，意思就是 必须是表名，和表字段
     * @param name
     * @return
     */
    @Query(value = "select * from employee where emp_name like %:name%",nativeQuery=true)
    public List<Employee> queryParamsLike2(@Param("name") String name);

    /**
     * 求取该表的记录总数
     * 利用原生的SQL语句，nativeQuery = true :支持原生SQL语句
     * @return
     */
    @Query(nativeQuery = true,value = "SELECT COUNT(*) from employee")
    public long getCount();


    /**
     * 根据id，来修改 员工记录
     *
     * 更新、删除操作
     *
     * @param id
     * @param name
     */
    @Modifying
    @Query("update Employee e set e.empname = :name where e.empid = :id")
    public void update(@Param("id")Integer id, @Param("name")String name);

    /**
     * 根据id，来删除员工信息  delete from employee where id = ?
     * 使用删除、更新操作，必须在该方法名在加上事务注解（ @Transactional）
     * @param id
     */
    public void deleteByEmpid(Integer id);


}
